package com.kasax.httpsupport;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Set;


/**
 * 网络请求的处理者
 */
public class RequestHandler implements IRequestHandler {
    @Override
    public Response handlerRequest(HttpCall call) throws IOException {
        HttpURLConnection urlConnection = manageConfig(call);
        if (!call.request.headers.isEmpty()) {
            addHeaders(urlConnection, call.request);
        }
        if (call.request.body != null) {
            writeContent(urlConnection, call.request.body);
        }
        if (!urlConnection.getDoOutput()) {
            urlConnection.connect();
        }
        int code = urlConnection.getResponseCode();
        if (code >= 200 && code <= 400) {
            byte[] bytes = new byte[1024 * 4];
            int len;
            InputStream in = urlConnection.getInputStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            while ((len = in.read(bytes)) != -1) {
                baos.write(bytes, 0, len);
            }
            Response response =
                    new Response.Builder().code(code).message(urlConnection.getResponseMessage()).body(new ResponseBody(baos.toByteArray()))
                            .build();
            try {
                in.close();
                urlConnection.disconnect();
            } finally {
                if (in != null) {
                    in.close();
                }
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
            }
            return response;
        }
        throw new IOException(String.valueOf(urlConnection.getResponseCode()));
    }

    /**
     * 向服务器写数据
     *
     * @param urlConnection
     * @param body
     * @throws IOException
     */
    private void writeContent(HttpURLConnection urlConnection, RequestBody body) throws IOException {
        OutputStream outputStream = urlConnection.getOutputStream();
        body.writeTo(outputStream);
    }

    /**
     * 给对象添加请求头
     *
     * @param urlConnection
     * @param request
     */
    private void addHeaders(HttpURLConnection urlConnection, Request request) {
        Set<String> keySet = request.headers.keySet();
        for (String key : keySet) {
            urlConnection.addRequestProperty(key, request.headers.get(key));
        }
    }

    /**
     * HttpUrlConnection基本参数的配置
     *
     * @param call
     * @return
     * @throws IOException
     */
    private HttpURLConnection manageConfig(HttpCall call) throws IOException {
        String url = call.request.url;
        URL urlObj = new URL(url);
        HttpURLConnection urlConnection = (HttpURLConnection) urlObj.openConnection();
        urlConnection.setConnectTimeout(call.config.connectTimeout);
        urlConnection.setReadTimeout(call.config.readTimeout);
        urlConnection.setDoInput(true);
        if (call.request.body != null && Request.HttpMethod.checkNeedBody(call.request.httpMethod)) {
            // 允许向服务器写数据
            urlConnection.setDoOutput(true);
        }
        return urlConnection;
    }
}
